package com.cs1.vue.工具类.数据库;

import com.cs1.vue.b设计包.SQL设计.SQLjson设计.SQLjson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SQL操作 {
	
	@Autowired
	private JdbcTemplate jdbc;
	// update 返回 受影响的行数
	@Value("${spring.datasource.库名}")
	private String 库名;
	
	final private String a = null;
	
	final public String get库名() {
		return 库名;
	}
	
	final public int 自定义(String sql, Object... s){
		return jdbc.update(sql,s);
	}
	
	final public int[] 自定义批处理(String sql, List<Object[]> s){return jdbc.batchUpdate(sql,s);}
	
	final public Map<String, Object> 自定义查Map(String sql,Object... s){
		return jdbc.queryForMap(sql,s);
	}
	
	public int 删(String 表名,String 条件,Object... s){
		String sql="delete from "+库名+"."+表名+" where "+条件;
		return jdbc.update(sql,s);
	}
	
	/**
	 * @param json null的列名值将被忽略
	 */
	public <T extends SQLjson> int 增(T json){
		String sql="insert into "+库名+"."+json.GetTableName()+" ";
		String q=" (";
		String h=") values (";
		List<Object> objects=new ArrayList<>();
		for(String v :json.Get列名s()){
			Object 值=json.Get列名value(v);
			if(值==null)
				continue;
			q+=v+",";
			h+="?,";
			objects.add(值);
		}
		if(q.equals(" ("))
			return 0;//没有值写入
		q=q.substring(0,q.length()-1);
		h=h.substring(0,h.length()-1);
		h+=")";
		sql+=q+h;
		return jdbc.update(sql,objects.toArray());
	}
	
	/**
	 * 修改什么列名需要在 [可修改列名] 中声明
	 */
	public <T extends SQLjson> int 改(T json,List<String> 可修改列名,String 条件,Object... s){
		String sql="update "+库名+"."+json.GetTableName()+" set ";
		List<Object> objects=new ArrayList<>();
		for(String v :可修改列名){
			Object 值=json.Get列名value(v);
			sql+=v+"=?,";
			objects.add(值);
		}
		if(objects.size()==0)
			return 0;//没有需要修改的值
		sql=sql.substring(0,sql.length()-1);
		sql+=" where "+条件;
		objects.addAll(List.of(s));
		return jdbc.update(sql,objects.toArray());
	}
	
	/**
	 *  @param json null的列名值将被忽略,不做修改
	 */
	public <T extends SQLjson> int 改(T json,String 条件,Object... s){
		List<String> list=new ArrayList<>();
		for(String v :json.Get列名s()){
			Object value=json.Get列名value(v);
			if(value==null)
				continue;
			list.add(v);
		}
		return this.改(json,list,条件,s);
	}
	
	/**
	 *  原生
	 */
	final public <T extends SQLjson> List<T> 查(Class<T> tClass,String sql, Object... s){
		return jdbc.query(sql,new BeanPropertyRowMapper<>(tClass),s);
	}
	
	/**
	 *  查找指定列,节省大量资源 <br/>
	 *  如果没有声明 列 ,则默认 获取所有列
	 */
	public <T extends SQLjson> List<T> 查(Class<T> tClass,List<String> 列名,String 接sql,Object... s){
		T t=this.newSQLjson(tClass);
		String sql="select ";
		if(列名==null||列名.size()==0)
			sql+=" * ";
		else {
			for (String v:列名)
				sql+=v+",";
			sql=sql.substring(0,sql.length()-1);
		}
		sql+=" from "+库名+"."+t.GetTableName()+" "+接sql;
		return this.查(tClass,sql,s);
	}
	
	/**
	 * 这个最常用
	 */
	public <T extends SQLjson> List<T> 查_条件(Class<T> tClass, String 条件,Object... s){
		return this.查(tClass,null," where "+条件,s);
	}
	
	/**
	 * 也很常用
	 */
	public <T extends SQLjson> List<T> 查_条件(Class<T> tClass,List<String> 列名, String 条件,Object... s){
		return this.查(tClass,列名," where "+条件,s);
	}
	
	
	/**
	 * 为了提供方便,有点强迫症
	 */
	private <T extends SQLjson> T newSQLjson(Class<T> tClass){
		try {
			return (T)tClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
}
